import * as THREE from 'three'

export const Shader = {
  uniforms: {
    'tDiffuse': {type: 't', value: null},
    'time': {type: 'f', value: -1.0}
  },
  vertexShader: `
    precision mediump float;
    precision mediump int;

    uniform mat4 modelViewMatrix;
    uniform mat4 projectionMatrix;

    attribute vec3 position;

    varying vec3 vPosition;

    void main() {
      vPosition = position;
      gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
    }
  `,
  fragmentShader(pointCount, centersCount = 1) {
    return `
    precision mediump float;
    precision mediump int;

    uniform float ratio;
    uniform vec3 centers[${centersCount}];
    uniform vec3 points[${pointCount}];

    varying vec3 vPosition;

    void main() {
      float dist = 100000000.0;
      float opacity = 0.0;
      vec3 pos = vec3(vPosition[0], vPosition[1], 0.0);

      // points

      // centers
      for (int i = 0; i < ${centersCount}; i++) {
        float d =  distance(pos, centers[i]) / 20.0;
        float color = 1.0 - d;
        float opa = 1.0 - abs(d - ratio) * 8.0;

        if (opa > opacity) {
          opacity = opa;
          dist = d;
        }
      }
      // float color = clamp(1.0 - dist, 0.0, 0.0);
      if (opacity > 0.1) {
        gl_FragColor =  vec4(opacity, 0.0, opacity, 1.0 - opacity);
      } else {
        gl_FragColor =  vec4(0.0, 0.2, 0.3, 1);
      }
    }
    `
  },
}

export function createMaterial(points = [[0, 0, 0]], center = [0, 0, 0]) {
  return new THREE.RawShaderMaterial({
    vertexShader: Shader.vertexShader,
    fragmentShader: Shader.fragmentShader(points.length),
    uniforms: {
      points: {
        value: points.map(p => new THREE.Vector3(...p))
      },
      centers: {
        value: [new THREE.Vector3(...center)],
      },
      ratio: {value: 0.1}
    },
  })
}

export function startAnimate({scene, renderer, camera}, material) {
  let ratio = 0.8
  const animate = () => {
    material.uniforms.ratio.value = ratio
    renderer.render(scene, camera)
    ratio = (ratio + 0.016) % 1
    requestAnimationFrame(animate)
  }
  animate()
}
